﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;

namespace Babel.SDK
{
    public class TargetAssemblyElement : XElement
    {
        #region Fields
        public static readonly string NodeTargetAssembly = "TargetAssembly";
        public static readonly string NodeNamespace = "Namespace";
        public static readonly string NodeInterface = "Interface";
        public static readonly string NodeClass = "Class";
        public static readonly string NodeStruct = "Struct";
        public static readonly string NodeEnum = "Enum";
        public static readonly string NodeEvent = "Event";
        public static readonly string NodeGet = "Get";
        public static readonly string NodeSet = "Set";
        public static readonly string NodeAdd = "Add";
        public static readonly string NodeRemove = "Remove";
        public static readonly string NodeInvoke = "Invoke";
        public static readonly string NodeField = "Field";
        public static readonly string NodeProperty = "Property";
        public static readonly string NodeMethod = "Method";
        public static readonly string NodeReturnType = "ReturnType";
        public static readonly string NodeParameter = "Parameter";
        public static readonly string NodeParameters = "Parameters";

        private TypeSignatureEqualityComparer _eq;
        private Dictionary<string, XElement> _namespaces;
        private Dictionary<string, XElement> _types;
        private Dictionary<string, XElement> _methods;
        
        #endregion

        #region Properties
        public string FullName
        {
            get
            {
                return this.Attribute("fullName").Value;
            }
        }

        #endregion

        #region Constructors
        public TargetAssemblyElement(XElement element)
            : base(element)
        {
            _namespaces = new Dictionary<string, XElement>();
            _types = new Dictionary<string, XElement>();
            _methods = new Dictionary<string, XElement>();
            _eq = new TypeSignatureEqualityComparer();
        }
        
        #endregion

        #region Methods
        public XElement FindNamespaceNode(string name)
        {
            XElement element;
            if (_namespaces.TryGetValue(name, out element))
            {
                element = (from ns in this.Elements(NodeNamespace)
                           where ns.Attribute("name").Value == name
                           select ns).FirstOrDefault();

                if (element != null)
                    _namespaces.Add(name, element);
            }

            return element;
        }

        public XElement FindTypeNode(string name)
        {
            XElement element;
            if (_types.TryGetValue(name, out element))
            {
                element = (from ns in this.Elements(NodeNamespace)
                           where ns.Attribute("name").Value == name
                           select ns).FirstOrDefault();

                if (element != null)
                    _types.Add(name, element);
            }

            return element;
        }
        
        #endregion
    }
}
